#include "RevanServer.h"

/* Funcion que crea el canal, lo enlaza con los datos y establece el numero de clientes en
 * la cola de conexiones.
 */
void RevanServer::Start()
{
	createSocket();
	makeBind();
	startListen();
	cout<<"El servidor esta a la escucha de clientes"<<endl;
}

/* Funcion que abre el canal de comunicaciones de tipo Socket y asigna 
 * los resultados en las estructuras de tipo sockaddr_in.
 */
void RevanServer::createSocket()
{
	if((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1){
		cout<<"Error al abrir canal socket"<<endl;
		exit(1);
	}
	
	/* Asignamos valores a la estructura */
	server_dir.sin_family = AF_INET;
	server_dir.sin_port = htons(port);
	server_dir.sin_addr.s_addr = INADDR_ANY;
	memset(&(server_dir.sin_zero), '\0', 8);
}

/* Funcion que enlaza la estructura server_dir con el canal de tipo socket
 * sockfd 
 */ 
void RevanServer::makeBind()
{
	if(bind(sockfd, (struct sockaddr *)&server_dir, sizeof(struct sockaddr_in)) == -1)
	{
		cout<<"Error al enlazar la estructura con el canal de comunicaciones."<<endl;
		exit(1);
	}
}

/* Funcion que espececifa el numero de clientes que pueden conectarse a el servidor.
 */
void RevanServer::startListen()
{
	if(listen(sockfd, backlog) == -1){
		cout<<"Error al establecer el numero de clientes en la cola de conexiones"<<endl;
		exit(1);
	}
}

/* Funcion que acepta una conexion entrante para el servidor.
 */
int RevanServer::acceptClient()
{
	socklen_t sin_size = sizeof(struct sockaddr_in);
	if((newfd = accept(sockfd, (struct sockaddr *)&client_dir, &sin_size)) == -1)
	{
		cout<<"Error al aceptar a un cliente."<<endl;
		exit(1);
	}
	cout<<"Cliente conectado con la direccion ip: ["<<inet_ntoa(client_dir.sin_addr)<<"]"<<endl;
	shutdown(sockfd, 2);
	return newfd;
}

void RevanServer::Close()
{
	close(sockfd);
	close(newfd);
}

/* Constructor 1 
 * Con opciones default 
 */
RevanServer::RevanServer()
{
	port = 14000;
	backlog = 50;
	strcpy(ip_adress, "127.0.0.1");
}

/* Constructor 2
 * ip - Direccion ip para el servidor.
 * port - Puerto para la escucha del servidor.
 */
RevanServer::RevanServer(char *ip, int p)
{
	port = p;
	backlog = 50;
	strcpy(ip_adress, ip);
}

/* Construcor 3
 * ip - Direccion ip para el servidor.
 * port - Puerto para la escucha del servidor.
 * backlog - Numero de clientes en cola para atender.
 */
RevanServer::RevanServer(char *ip, int p, int backlog)
{
	port = p;
	backlog = backlog;
	strcpy(ip_adress, ip);
}

/* Destructor */
RevanServer::~RevanServer()
{
	port = 0;
	backlog = 0;
	strcpy(ip_adress, "");
	close(sockfd);
	close(newfd);
}

